using System;

namespace UGent.Tsp
{
    public class MapStatistics
    {
        public static void RunOnConsole()
        {
            Console.WriteLine("Enter the name of the map.");
            string line = Console.ReadLine();
            Map map = new Map(line);
            
            Console.WriteLine("Number of cities: {0}. Minimum length: {1}. Maximum length {2}", map.CityCount, map.LowerBound, map.UpperBound);
            
            // Calculate the average intercity distance
            Results results = new Results();
            for(int i = 0; i < map.CityCount; i++)
            {
                for(int j = i + 1; j < map.CityCount; j++)
                    results.Add(map.GetDistance(i, j));
            }
            
            double averageDistance = results.GetAverage();
            
            Console.WriteLine("Average intercity distance: {0} +/- {1} (sigma = {2}).", results.GetAverage(), results.GetRootMeanSquareError(), results.GetDeviation());
            
            // Calculate the average square intercity distance
            results = new Results();
            for(int i = 0; i < map.CityCount; i++)
            {
                for(int j = i + 1; j < map.CityCount; j++)
                    results.Add(map.GetDistance(i, j) * map.GetDistance(i, j));
            }
            
            double averageDistanceSquared = results.GetAverage();
            
            Console.WriteLine("Average squared intercity distance: {0} +/- {1} (sigma = {2}).", results.GetAverage(), results.GetRootMeanSquareError(), results.GetDeviation());
            
            // Calculate the correlation project;
            results = new Results();
            for(int i = 0; i < map.CityCount; i++)
            {
                for(int j = i + 1; j < map.CityCount - 1; j++)
                    for(int k = j + 1; k < map.CityCount; k++)
                        results.Add(map.GetDistance(i, j) * map.GetDistance(j, k));
            }
            
            double correlation = results.GetAverage();
            
            Console.WriteLine("Average intercity distance correlation: {0} +/- {1} (sigma = {2}).", results.GetAverage(), results.GetRootMeanSquareError(), results.GetDeviation());
            
            Console.WriteLine("Average route length: {0}", map.CityCount * averageDistance);
            Console.WriteLine("Route deviation: {0}", Math.Sqrt((2.0 - 3.0*map.CityCount)*averageDistance*averageDistance + map.CityCount * averageDistanceSquared + (2.0 * map.CityCount - 2.0)*correlation));
            
            // Do a MCMC simulation to get the right values
            MarkovCluster cluster = new MarkovCluster();
            cluster.ConfigureOnConsole();
            cluster.ConfigureSimulationOnConsole();
            cluster.MaximumSteps = 50000000000;
            
            Metropolis metropolis = new Metropolis(cluster);
            metropolis.Beta = 0;
            metropolis.Run();
            
            results = metropolis.Results;
            
            Console.WriteLine("Average route distance: {0} +/- {1}. Deviation: {2}", results.GetAverage(), results.GetRootMeanSquareError(), results.GetDeviation());
        }
    }
}